package com.gql.streamAPI;

import com.gql.methodReferences.Employee;
import com.gql.methodReferences.EmployeeData;
import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * description: 终止操作
 * @author: gql
 * @date: 2022/04
 */
public class EndTest {
    /**
     * 1.1匹配与查找
     */
    @Test
    public void end01Test() {
        List<Employee> employeeList = EmployeeData.getEmployees();
        // 1.allMatch (是否所有员工的年龄都大于18)
        boolean flag = employeeList.stream().allMatch(employee -> employee.getAge() > 18);
        System.out.println("flag = " + flag);

        // 2.anyMatch (是否存在员工工资大于10000)
        boolean flag2 = employeeList.stream().anyMatch(employee -> employee.getSalary() > 10000);
        System.out.println("flag2 = " + flag2);

        // 3.noneMatch (是否没有匹配的元素)
        boolean flag3 = employeeList.stream().noneMatch(employee -> employee.getName().startsWith("雷"));
        System.out.println("flag3 = " + flag3);

        // 4.findFirst (返回第一个元素)
        Optional<Employee> first = employeeList.stream().findFirst();
        System.out.println("first = " + first);

        // 5.findAny (随机返回一个元素)
        Optional<Employee> any = employeeList.stream().findAny();
        System.out.println("any = " + any);
    }

    /**
     * 1.2查找与匹配
     */
    @Test
    public void end02Test() {
        List<Employee> employeeList = EmployeeData.getEmployees();
        // 1.count (返回工资大于5000的员工个数)
        long count = employeeList.stream().filter(employee -> employee.getSalary() > 5000).count();
        System.out.println("count = " + count);

        // 2.max (返回最高的工资) 取出流的最右边
        Stream<Double> salaryStream = employeeList.stream().map(Employee::getSalary);
        Optional<Double> maxSalary = salaryStream.max(Double::compare);
        System.out.println("maxSalary = " + maxSalary);


        // 3.min (返回工资最低的员工) 取出流的最左边
        Optional<Employee> minEmployee = employeeList.stream().min(Comparator.comparingDouble(Employee::getSalary));
        System.out.println("minEmployee = " + minEmployee);

        // 4.forEach (内部迭代,相对于Collection的外部迭代而言)
        employeeList.stream().forEach(System.out::println);
        // 集合的遍历操作(更快)
        employeeList.forEach(System.out::println);
    }

    /**
     * 测试 employeeList.stream().forEach和employeeList.forEach谁快
     * 测试结果:随着数据量的增大,后者更快
     */
    @Test
    public void myTest() {
        List<Employee> employeeList = EmployeeData.getEmployees();
        long start1 = System.currentTimeMillis();
        employeeList.stream().forEach(System.out::println);
        long end1 = System.currentTimeMillis();
        System.out.println("end1-start1 = " + (end1 - start1));

        long start2 = System.currentTimeMillis();
        employeeList.forEach(System.out::println);
        long end2 = System.currentTimeMillis();
        System.out.println("end2-start2 = " + (end2 - start2));
    }

    /**
     * 测试规约
     */
    @Test
    public void reduceTest() {
        // 1.reduce (计算1-10的和) 可以将流中元素反复结合起来,得到一个值,返回T
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println("reduce = " + reduce);

        // 2.reduce (计算公司所有员工工资总和) 可以将流中元素反复结合起来,得到一个值,返回Optional<T>
        List<Employee> employeeList = EmployeeData.getEmployees();
        Optional<Double> reduce1 = employeeList.stream().map(Employee::getSalary).reduce(Double::sum);
        System.out.println("reduce1 = " + reduce1);
    }

    /**
     * 测试收集
     */
    @Test
    public void collectTest() {
        List<Employee> employeeList = EmployeeData.getEmployees();
        // 1.collect (查找工资大于6000的员工,结果返回一个list或Set或Map)
        List<Employee> employeeList1 = employeeList.stream().
                filter(employee -> employee.getSalary() > 6000)
                .collect(Collectors.toList());
        employeeList1.forEach(System.out::println);

        // 1.2 转换为set
        Set<Employee> employeeSet = employeeList.stream()
                .filter(employee -> employee.getSalary() > 6000)
                .collect(Collectors.toSet());
        employeeSet.forEach(System.out::println);
    }
}

















